package com.atguigu.tingshu.album.service.impl;

import com.atguigu.tingshu.album.mapper.AlbumAttributeValueMapper;
import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.mapper.AlbumStatMapper;
import com.atguigu.tingshu.album.mapper.TrackInfoMapper;
import com.atguigu.tingshu.album.service.AlbumAttrandValueService;
import com.atguigu.tingshu.album.service.AlbumInfoService;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.rabbit.constant.MqConst;
import com.atguigu.tingshu.common.rabbit.service.RabbitService;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.album.AlbumAttributeValue;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.AlbumStat;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.query.album.AlbumInfoQuery;
import com.atguigu.tingshu.vo.album.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class AlbumInfoServiceImpl extends ServiceImpl<AlbumInfoMapper, AlbumInfo> implements AlbumInfoService {

    @Autowired
    private AlbumInfoMapper albumInfoMapper;
    @Autowired
    private AlbumAttributeValueMapper attributeValueMapper;
    @Autowired
    private AlbumStatMapper albumStatMapper;
    @Autowired
    private TrackInfoMapper trackInfoMapper;
    @Autowired
    private AlbumAttrandValueService albumAttrandValueService;
    @Autowired
    private RabbitService rabbitService;
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Transactional(rollbackFor = Exception.class)  // spring事务只能感知到运行时异常或者error
    @Override
    public void saveAlbumInfo(AlbumInfoVo albumInfoVo) {
        AlbumInfoServiceImpl proxy = (AlbumInfoServiceImpl) AopContext.currentProxy();

        //1.保存基本数据album_info
        AlbumInfo albumInfo = new AlbumInfo();
        BeanUtils.copyProperties(albumInfoVo, albumInfo);
        Long userId = AuthContextHolder.getUserId();
        albumInfo.setUserId(userId);
        albumInfo.setStatus(SystemConstant.ALBUM_STATUS_PASS);
        if (!SystemConstant.ALBUM_PAY_TYPE_FREE.equals(albumInfo.getPayType())) {
            albumInfo.setTracksForFree(5);
        }
        albumInfoMapper.insert(albumInfo);
        //2.向专辑属性值保存数据base_attribute_value
        List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoVo.getAlbumAttributeValueVoList();
        for (AlbumAttributeValueVo albumAttributeValueVo : albumAttributeValueVoList) {
            AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();
            albumAttributeValue.setAlbumId(albumInfo.getId());
            albumAttributeValue.setAttributeId(albumAttributeValueVo.getAttributeId());
            albumAttributeValue.setValueId(albumAttributeValueVo.getValueId());
            attributeValueMapper.insert(albumAttributeValue);
        }


        //3.初始化专辑统计表（album_stat为专辑的四个统计维度赋初始值）
        proxy.initAlbumStat(albumInfo.getId());//代理对象

        //4.将专辑对象保存到es中去
        if(albumInfo.getIsOpen().equals("1")){
            rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM,MqConst.ROUTING_ALBUM_UPPER,albumInfo.getId().toString());
            log.info("专辑微服务发送消息到搜索微服务的指定队列中:{}上架成功",albumInfo.getId());
        }
    }

    @Override
    public Page<AlbumListVo> findUserAlbumPage(Page<AlbumListVo> albumInfovVoPage, AlbumInfoQuery albumInfoQuery) {
        return albumInfoMapper.findUserAlbumPage(albumInfovVoPage, albumInfoQuery);
    }

    @Override
    public AlbumInfo  getAlbumInfo(Long albumId) {
        AlbumInfo albumInfo = albumInfoMapper.selectById(albumId);
        if (null == albumInfo) {
            throw new GuiguException(201, "无专辑");
        }
        List<AlbumAttributeValue> albumAttributeValueList = attributeValueMapper.selectList(new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, albumId));
        albumInfo.setAlbumAttributeValueVoList(albumAttributeValueList);
        return albumInfo;
    }

    @Transactional(rollbackFor = Exception.class)  // spring事务只能感知到运行时异常或者error
    @Override
    public void updateAlbumInfo(AlbumInfoVo albumInfoVo, Long userId, Long albumId) {
        //todo 先删除缓存
        String cacheKey = RedisConstant.CACHE_INFO_PREFIX+albumId;
        redisTemplate.delete(cacheKey);


        //修改专辑基本信息
        AlbumInfo albumInfo = albumInfoMapper.selectById(albumId);
        if (null == albumInfo) {
            throw new GuiguException(201, "专辑不存在");
        }
        BeanUtils.copyProperties(albumInfoVo,albumInfo);
        if (albumInfoVo.getPayType().equals(SystemConstant.ALBUM_PAY_TYPE_FREE)){
            albumInfo.setTracksForFree(0);
            albumInfo.setDiscount(new BigDecimal("-1.00"));
            albumInfo.setVipDiscount(new BigDecimal("-1.00"));
            albumInfo.setPrice(new BigDecimal("0"));
        }else {
            albumInfo.setTracksForFree(5);
        }
        albumInfoMapper.updateById(albumInfo);

        //修改专辑属性信息
        //1.删除老标签信息
        attributeValueMapper.delete(new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId,albumId));
        //2.新增新标签信息
        List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoVo.getAlbumAttributeValueVoList();

        List<AlbumAttributeValue> albumAttributeValueVos = albumAttributeValueVoList.stream().map(albumAttributeValueVo -> {
            AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();
            albumAttributeValue.setAlbumId(albumId);
            albumAttributeValue.setAttributeId(albumAttributeValueVo.getAttributeId());
            albumAttributeValue.setValueId(albumAttributeValueVo.getValueId());
            return albumAttributeValue;
        }).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(albumAttributeValueVos)){
            albumAttrandValueService.saveBatch(albumAttributeValueVos);
        }

        //todo 专辑同步到es
        if(albumInfo.getIsOpen().equals("1")){
            rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM,MqConst.ROUTING_ALBUM_UPPER,albumInfo.getId().toString());
            log.info("专辑微服务发送消息到搜索微服务的指定队列中:{}上架成功",albumInfo.getId());
        }else {
            rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM, MqConst.ROUTING_ALBUM_LOWER, albumId.toString());
            log.info("专辑微服务发送消息到搜索微服务指定的队列，完成专辑：{}下架成功：", albumId);
        }
    }
    @Override
    public void removeAlbumInfo(Long albumId) {
        //删除专辑基本信息
        Long count = trackInfoMapper.selectCount(new LambdaQueryWrapper<TrackInfo>().eq(TrackInfo::getAlbumId, albumId));
        if (count > 0) {
            throw new GuiguException(201, "该专辑下存在声音，请勿删除");
        }
        albumInfoMapper.deleteById(albumId);
        //删除专辑统一信息
        albumStatMapper.delete(new LambdaQueryWrapper<AlbumStat>().eq(AlbumStat::getAlbumId, albumId));
        //删除专辑属性信息
        attributeValueMapper.delete(new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, albumId));
        //同步专辑到es
        rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM, MqConst.ROUTING_ALBUM_LOWER, albumId.toString());
        log.info("专辑微服务发送消息到搜索微服务指定的队列，完成专辑：{}下架成功：", albumId);
    }

    @Override
    public List<AlbumInfo> findUserAllAlbumList(Long userId) {
        LambdaQueryWrapper<AlbumInfo> queryWrapper =  new LambdaQueryWrapper<>();
        queryWrapper.eq(AlbumInfo::getUserId, userId).eq(AlbumInfo::getIsDeleted,0);
        List<AlbumInfo> albumInfos = albumInfoMapper.selectList(queryWrapper);
        return albumInfos;
    }

    @Override
    public AlbumStatVo getAlbumInfoStat(Long albumId) {
        return albumInfoMapper.getAlbumInfoStat(albumId);
    }

    @Override
    public List<TrackListVo> getTrackInfoList(List<Long> collectTrackIds) {
        List<TrackInfo> trackInfos = trackInfoMapper.selectBatchIds(collectTrackIds);
        List<TrackListVo> collect = trackInfos.stream().map(trackInfo -> {
            TrackListVo trackListVo = new TrackListVo();
            BeanUtils.copyProperties(trackInfo, trackListVo);
            trackListVo.setTrackId(trackInfo.getId());
            return trackListVo;
        }).collect(Collectors.toList());
        return collect;
    }

    @Override
    public List<Long> getAlbumIds() {
        List<AlbumInfo> albumInfos = albumInfoMapper.selectList(null);
        return albumInfos.stream().map(AlbumInfo::getId).collect(Collectors.toList());
    }

    @Transactional
    public void initAlbumStat(Long albumId) {
        ArrayList<String> albumStatsType = new ArrayList<>();
        albumStatsType.add(SystemConstant.ALBUM_STAT_PLAY);
        albumStatsType.add(SystemConstant.ALBUM_STAT_SUBSCRIBE);
        albumStatsType.add(SystemConstant.ALBUM_STAT_BROWSE);
        albumStatsType.add(SystemConstant.ALBUM_STAT_COMMENT);
        for (String album : albumStatsType) {
            AlbumStat albumStat = new AlbumStat();
            albumStat.setAlbumId(albumId);
            albumStat.setStatType(album);
            albumStat.setStatNum(0);
            albumStatMapper.insert(albumStat);
        }
    }
}
